package com.trajan.exercise.reflection;

/*

   Created with IntelliJ IDEA.

   Ing. Tomáš Herich
   --------------------------- 
   14. 07. 2013
   1:43 PM

*/

import com.trajan.exercise.datastructure.HashCodeEqualsOverride;
import com.trajan.exercise.datastructure.LinkedList;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectionExample {

    public static void main(String[] args) {


        ReflectionExample example = new ReflectionExample();

        try {
            example.reflectionInfoTest();
            example.reflectionTest();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }

    public void reflectionTest() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        System.out.println("Reflection test\n");
        System.out.println("------------------------------------");

        Class myClass = LinkedList.class;

        Object instance = myClass.newInstance();

        Method addNode = myClass.getMethod("addNode", Object.class);
        Method inOrderTraverse = myClass.getMethod("inOrderTraverse", null);

        addNode.invoke(instance, 1);
        addNode.invoke(instance, 2);
        addNode.invoke(instance, 3);
        addNode.invoke(instance, 4);

        inOrderTraverse.invoke(instance, null);


    }

    public void reflectionInfoTest() throws ClassNotFoundException {

        Class myClass1 = LinkedList.class;
        Class myClass2 = Class.forName("com.trajan.exercise.datastructure.BinaryTree");

        Object object = new HashCodeEqualsOverride(10, "Test", "Tester");
        Class myClass3 = object.getClass();

        displayClassInfo(myClass1);
        displayClassInfo(myClass2);
        displayClassInfo(myClass3);

    }

    public void displayClassInfo(Class myClass) {

        System.out.println("\n\nClass: " + myClass.getSimpleName());
        System.out.println("------------------------------------");

        System.out.println("\nFields:");
        displayClassFields(myClass);

        System.out.println("\nMethods:");
        displayClassMethods(myClass);

        System.out.println("\nAttributes:");
        displayClassModifiers(myClass);

        System.out.println("\n\n");


    }

    public void displayClassFields(Class myClass) {

        Field[] fields = myClass.getDeclaredFields();

        for(Field field : fields) {
            System.out.println("- " + field.getName());
        }
    }

    public void displayClassMethods(Class myClass) {

        Method[] methods = myClass.getMethods();

        for(Method method : methods) {
            System.out.println("- " + method.getName());
        }
    }

    public void displayClassModifiers(Class myClass) {

        int modifiers = myClass.getModifiers();

        System.out.println("- " + Modifier.toString(modifiers));

    }


}
